// ignore_for_file: must_be_immutable

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:yt_devops/components/brn/brn_bottom_button_panel.dart';
import 'package:yt_devops/components/gaps.dart';
import 'package:yt_devops/configs.dart';
import 'package:yt_devops/model/device_obj/data_type_model.dart';
import 'package:yt_devops/model/device_obj/output_data_model.dart';
import 'package:yt_devops/model/device_obj/services_model.dart';
import 'package:yt_devops/model/device_obj/spec/array_spec.dart';
import 'package:yt_devops/model/device_obj/spec/double_spec.dart';
import 'package:yt_devops/model/device_obj/spec/struct_spec.dart';
import 'package:yt_devops/pages/devices/device_tab/device_detail/ems/self_develop_ems_romote_control/ems_params_setting/widgets/energy_manage_set/widget/arrray_widget.dart';
import 'package:yt_devops/pages/site/site_setting/siet_elec_price_setting/add_mains_electricity_price/views/effective_data_widget.dart';
import 'package:yt_devops/resources/str_res_keys.dart';
import 'package:yt_devops/services/device/device_sevices.dart';
import 'package:yt_devops/styles/styles.dart';

import 'package:yt_devops/pages/site/site_setting/site_setting_base_info/widgets/item_widget.dart'
    as text_input_widget;
import 'package:yt_devops/utils/func_utils.dart';
import 'package:yt_devops/utils/number_input_limit_formatter.dart';
import 'package:yt_devops/utils/toast_utils.dart';

class EnergyManageSetView extends StatefulWidget {
  /// 设备ID
  final String deviceId;

  /// [servicesList] 是 [id] 相同的 [ServicesModel]集合
  final List<ServicesModel> servicesList;

  /// 取消回调
  final Function? cancelCallBack;

  /// 下发回调
  final Function(bool success, {Map<String, dynamic>? data})? confirmCallBack;

  final Map<String, dynamic> dataSource;

  const EnergyManageSetView(
      {Key? key,
      required this.deviceId,
      this.servicesList = const [],
      this.dataSource = const {},
      this.confirmCallBack,
      this.cancelCallBack})
      : super(key: key);

  @override
  State<EnergyManageSetView> createState() => _EnergyManageSetViewState();
}

class _EnergyManageSetViewState extends State<EnergyManageSetView> {
  final Map<String, dynamic> formData = {};

  @override
  initState() {
    initData();
    super.initState();
  }

  initData() {
    Map<String, dynamic> originDataSource =
        jsonDecode(jsonEncode(widget.dataSource));
    originDataSource.forEach((key, value) {
      for (var i = 0; i < widget.servicesList.length; i++) {
        var idx = widget.servicesList[i].outputData
            .indexWhere((element) => element.id == key);
        if (idx > -1) {
          var data = value;

          formData.putIfAbsent(key, () => data);
        }
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Gaps.vGap10,
        Expanded(
            child: ListView.separated(
          itemCount: widget.servicesList.length,
          itemBuilder: (context, index) =>
              outputServicesBuilder(widget.servicesList[index]),
          separatorBuilder: (context, index) => Gaps.vGap10,
        )),
        Align(
          alignment: Alignment.bottomCenter,
          child: DecoratedBox(
            decoration: const BoxDecoration(color: Colour.white),
            child: SafeArea(
              child: YtBrnBottomButtonPanel(
                mainButtonName: 'siteMonitor.issueParameters'.tr,
                mainButtonOnTap: () {
                  if (FocusScope.of(context).hasFocus) {
                    FocusScope.of(context).unfocus();
                  }
                  if (validate(widget.servicesList, formData)) {
                    sendCommand(widget.deviceId, widget.servicesList[0].id,
                        formData, widget.confirmCallBack);
                  }
                },
                secondaryButtonOnTap: () {
                  if (widget.cancelCallBack != null) {
                    widget.cancelCallBack?.call();
                  }
                },
                secondaryButtonName: ResKey.cancel.tr,
                enableSecondaryButton: true,
                secondaryButtonBorder: Border.all(color: Colour.dividerColor),
              ),
            ),
          ),
        ),
      ],
    );
  }

  /// 按照指令集合渲染的样式列表
  ListView outputServicesBuilder(ServicesModel servicesModel) {
    return ListView.separated(
      physics: const NeverScrollableScrollPhysics(),
      padding: EdgeInsets.zero,
      shrinkWrap: true,
      itemBuilder: (context, outputIdx) {
        if (outputIdx == 0) {
          return headTitleWidget(servicesModel.name);
        } else {
          var instruction = servicesModel.outputData[outputIdx - 1];
          DataTypeModel dataType = instruction.dataType;
          // Map spec;
          switch (instruction.dataType.type) {
            case DataTypeEnum.double:
            case DataTypeEnum.long:
              var spec = dataType.specs as DoubleSpec;
              List<TextInputFormatter>? inputFormatters;

              if (spec.max != null || spec.min != null) {
                num max = spec.max ?? 100000000, min = spec.min ?? 0;

                inputFormatters = [
                  NumberInputLimitFormatter(
                    max: max,
                    min: min,
                  )
                ];
              }

              return text_input_widget.ItemWidget(
                instruction.name,
                TextEditingController(
                    text: formData[instruction.id]?.toString() ?? ''),
                isRequired: true,
                unitString: spec.unit ?? '',
                titleColor: Colour.lightTextColor,
                titleFont: 14,
                isCanEdit: true,
                isShowDivider: false,
                inputTextWidth: 150,
                inputFormatters: inputFormatters,
                textInputType:
                    const TextInputType.numberWithOptions(decimal: true),
                textChangeCallBack: (value) {
                  if (formData[instruction.id] == null) {
                    formData.putIfAbsent(instruction.id, () => value);
                  } else {
                    formData[instruction.id] = value;
                  }
                },
              );
            case DataTypeEnum.timeRange:
              var range = formData[instruction.id]?.split('-') ?? ['', ''];
              return EffectiveDataWidget(
                context,
                instruction.name,
                range[0],
                range[1],
                (startDateTime, endDateTime) {
                  var time = '$startDateTime-$endDateTime';

                  formData[instruction.id] = time;
                  setState(() {});
                },
                () {},
                isShowHour: true,
                isDelete: true,
                isEdit: true,
              );

            case DataTypeEnum.array:
              var spec = dataType.specs as ArraySpec;
              return ArrayWidget(
                arrayModel: spec.item!,
                maxLength: spec.size,
                name: instruction.name,
                dataSource: formData[instruction.id] ?? [],
                onChange: (d) {
                  formData[instruction.id] = d;
                },
              );
            default:
              return Gaps.empty;

            /// 目前只实现ui里已有的样式， 其他类型均返回 Gaps.empty
          }
        }
      },
      separatorBuilder: (context, index) => const Divider(
        height: 1,
      ),
      itemCount: servicesModel.outputData.length + 1,
    );
  }

  Widget headTitleWidget(String title) {
    return Container(
      height: 53,
      color: Colour.white,
      padding: EdgeInsets.fromLTRB(16.w, 0, 16.w, 0),
      child: Container(
        height: 53,
        alignment: Alignment.centerLeft,
        child: Text(
          title,
          style: TextStyle(
            fontSize: 18.sp,
            fontWeight: FontWeight.w600,
          ),
        ),
      ),
    );
  }

  /// 验证是否所有参数已填
  bool validate(List<ServicesModel> services, Map<String, dynamic> data) {
    List<OutputDataModel> outputData = [];
    outputData = services.fold(outputData,
        (previousValue, element) => previousValue..addAll(element.outputData));
    if (data.isEmpty) {
      TotastUtils.tip(Get.context!,
          title: ResKey.devicePleaseEnterValue.tr); //'请输入要下发的参数'
      return false;
    }
    for (var output in outputData) {
      var key = output.id;
      var value = data[key];

      if (value is List) {
        for (var item in value) {
          if (item is Map) {
            for (var k in item.keys) {
              if (item[k] == null || item[k] == '' || item[k] == '-') {
                var struct = (output.dataType.specs as ArraySpec).item?.specs
                    as StructSpec;
                var idx =
                    struct.specs!.indexWhere((element) => element.id == k);
                if (idx > -1) {
                  TotastUtils.tip(Get.context!,
                      title: '${ResKey.plsInput.tr}${struct.specs![idx].name}');
                  return false;
                }
              }
            }
          }
        }
      } else if (value is Map) {
        for (var k in value.keys) {
          if (value[k] == null) {
            var struct = output.dataType.specs as StructSpec;
            var idx = struct.specs!.indexWhere((element) => element.id == k);
            if (idx > -1) {
              TotastUtils.tip(Get.context!,
                  title: '${ResKey.plsInput.tr}${struct.specs![idx].name}');
              return false;
            }
          }
        }
      } else {
        if (value == null && output.dataType.type != DataTypeEnum.array) {
          TotastUtils.tip(Get.context!,
              title: '${ResKey.plsInput.tr}${output.name}');
          return false;
        }
      }
    }
    return true;
  }

  ///下发指令
  void sendCommand(
          String deviceId,
          String serviceId,
          Map<String, dynamic> data,

          ///确认回调
          Function(bool success, {Map<String, dynamic>? data})?
              confirmHandler) =>
      Configs.httpClient.requestWithLoading(
        () async {
          Map<String, dynamic> params = {
            'deviceId': deviceId,
            'serviceId': serviceId,
            'input': data
          };
          await DeviceServices().deviceRemoteSetting(params);
          FuncUtils.requestTipsDislog(
              Get.context!, ResKey.executeSuccess.tr, true);
          if (mounted) {}
          Future.delayed(
            const Duration(
              milliseconds: 1000,
            ),
            () {
              Get.back();
              confirmHandler?.call(true, data: data);
            },
          );
        },
        onError: (err) {
          FuncUtils.requestTipsDislog(
              Get.context!, ResKey.executeFailure.tr, false);

          Future.delayed(
            const Duration(
              milliseconds: 1000,
            ),
            () => Get.back(),
          );
          confirmHandler?.call(false);
          return true;
        },
      );
}
